package patterns;

// 模板类，定义了制作饮料的通用流程
public class LearnTemplate {
    public static void main(String[] args) {
        // 很好理解，就是在最顶层的抽象类定义一组行为，不同的实现类根据规定好的顺序进行不同实现。
        // 模板方法模式定义了一个算法的骨架，把具体的步骤延迟到子类中去实现，
        // 允许子类在不改变算法结构的情况下重定义某些步骤的实现方式。
        Drink coffee = new Coffee();
        coffee.make();
        System.out.println("-----");
        Drink tea = new Tea();
        tea.make();
    }
}

// 抽象模板类，定义流程框架
abstract class Drink {
    // 模板方法：定义了算法的固定流程（不可修改）
    public final void make() {
        boilWater();
        brew();
        pourInCup();
        if (needCondiments()) {
            addCondiments();
        }
    }

    // 公共步骤
    void boilWater() {
        System.out.println("烧开水");
    }

    void pourInCup() {
        System.out.println("倒入杯中");
    }

    // 抽象方法：由子类具体实现
    abstract void brew();            // 冲泡方法
    abstract void addCondiments();   // 添加调料

    // 钩子方法：子类可选择性重写
    boolean needCondiments() {
        return true;
    }
}

// 实现类：咖啡
class Coffee extends Drink {
    @Override
    void brew() {
        System.out.println("用热水冲泡咖啡");
    }

    @Override
    void addCondiments() {
        System.out.println("加入糖和牛奶");
    }
}

// 实现类：茶
class Tea extends Drink {
    @Override
    void brew() {
        System.out.println("用热水浸泡茶叶");
    }

    @Override
    void addCondiments() {
        System.out.println("加柠檬片");
    }

    @Override
    boolean needCondiments() {
        return false;  // 不加调料
    }
}
